
#ifndef _TTG_SERVICES_PUBLISHERBASE_
#define _TTG_SERVICES_PUBLISHERBASE_

#include "Runtime.Low/Services/Service.h"
#include "Runtime.Low/Services/Logger/Logger.h"
#include "Common/Structures.h"
#include "Subscribers.h"
#include "PublisherInfo.h"

namespace ttg
{
	namespace services
	{
		class CommonPublisher;

		//Base static class, which contains and provides information about all known publishers.
		class PublisherBase :public Service
		{
			private:
				static PublisherBase *ref;
			private:
				structures::Dictionary<PublisherInfo> *publishers;
				CommonPublisher *cp;
				std::list<TTGTriple<const char *,
						  Subscriber *,
						  void (*)(Subscriber *ss, Event *ev)>> delayed;
			protected:
				//TTGService member. Calls create().
				virtual void startUnSafe(std::vector<Service *> &deps, const char *params);
				//TTGService member. Calls release().
				virtual void stopUnSafe();
			public:
				PublisherBase();
				//Adds PublisherInfo to base.
				//Note: PublisherInfo * will NOT be released by destructor.
				void regPublisher(PublisherInfo *p);
				//Removes PublisherInfo from base.
				void unregPublisher(PublisherInfo *p);
				//Subscribes given Subscriber to given publisher.
				bool subscribe(const char *publisher, Subscriber *s, void (*d)(Subscriber *ss, Event *ev));
				//Subscribes given Subscriber to given publisher when base starts and publisher is registered.
				//Note: this methods never returns error.
				void subscribeAsSoonAsPossible(const char *publisher, Subscriber *s, void (*d)(Subscriber *ss, Event *ev));
				//Removes subscription.
				void desubscribe(const char *publisher, Subscriber *s);
				//Returns publisher for events with unnamed publishers (e.g. onExit).
				inline CommonPublisher &getCommonPublisher()
						{ return *cp; }
				virtual ~PublisherBase();
				//Returns reference to the istance (which always exists).
				inline static PublisherBase *getRef()
				{ return ref == NULL ? (ref = new PublisherBase()) : ref; }
		};
	}
}

#endif
